#include "gtc_protocol.h"
#include "gtc_client_pal.h"
#include "utility.h"
#include "MQTTClient.h"

#include <string.h>
#include <stdlib.h>

#define MQTT_SNED_BUF_LEN               (1500)   /*发送buff size*/
#define MQTT_RECV_BUF_LEN               (1500)   /*接收buff size*/
#define MQTT_CMD_TIMEOUT                (15000)  /*发送后等待接收的延时*/
#define MQTT_KEEP_LIVE_SEC              (20)     /*心跳包间隔秒数*/

struct MqttBase{
	uint32_t masterSerialNum;
	uint16_t heart_index;
	char_t *address;
	uint16_t port;
	char_t *username;
	char_t *password;
	char_t *topic;
    Network network;
	MQTTClient client;
    os_queue_t queue;
	uint8_t	sendbuf[MQTT_SNED_BUF_LEN];
	uint8_t recvbuf[MQTT_RECV_BUF_LEN];
};

static struct MqttBase mqtt_base;
static uint8_t test_flag = 0;

void client_set_test_flag(uint8_t state){
    test_flag = state;
}

void gtc_mqtt_send_poll(void){
    char topic[32] = {0};
    struct MqttSendMsg msg={0};
    if (os_queue_read(mqtt_base.queue, &msg)){
        if (test_flag){
            printf("<<<<<MqttSend len:%d <%s>\r\n", (int)strlen(msg.data), msg.data);
        }
        MQTTMessage message;
        
        strcat(topic, "server/");
        strcat(topic, mqtt_base.topic);

        message.qos = (enum QoS)msg.qos;
        message.retained = 0;
        message.dup = 0;
        message.payload = msg.data;
        message.payloadlen = strlen(msg.data);
        MQTTPublish(&mqtt_base.client, topic, &message);
    }
}

void gtc_mqtt_sycle(void){
    MQTTYield(&mqtt_base.client, 100);
    gtc_mqtt_send_poll();
}


void mqtt_deal_msg(char_t *str);
static void mqtt_msg_arrived(MessageData *data) {
    if (test_flag){
        printf(">>>>> len:%d <%s>\r\n", (int)data->message->payloadlen, (char *)data->message->payload);
    }
    mqtt_deal_msg(data->message->payload);
    memset(data->message->payload, 0, data->message->payloadlen);
}

int32_t mqtt_send_msg(struct MqttSendMsg *msg){
    return os_queue_send(mqtt_base.queue, msg);
}

int32_t mqtt_is_connect(void){
    return MQTTIsConnected(&mqtt_base.client);
}

int32_t mqtt_connect(void) {
    int32_t ret;
    MQTTPacket_connectData connectData = MQTTPacket_connectData_initializer;
    
    /*socket 连接*/
    ret = NetworkConnect(&mqtt_base.network, mqtt_base.address, mqtt_base.port);
    if (ret != 0){
        printf("socket connect fail\r\n");
        return -1;
    }
    //printf("network connect success\r\n");
    /*mqtt 连接*/
    connectData.MQTTVersion = 3;
    connectData.clientID.cstring = mqtt_base.topic;
    connectData.keepAliveInterval = MQTT_KEEP_LIVE_SEC;
    connectData.cleansession = 1;

    connectData.username.cstring = mqtt_base.username;
    connectData.password.cstring = mqtt_base.password;
 
    if( MQTTConnect(&mqtt_base.client, &connectData) != 0){
        printf("mqtt connect fail\r\n");
        return -1;
    }
    //printf("mqtt connect success topic:%s\r\n",mqtt_base.topic);
    /*mqtt 订阅*/
    if (MQTTSubscribe(&mqtt_base.client, mqtt_base.topic, (enum QoS)1, mqtt_msg_arrived)){
        printf("mqtt subscribe fail\r\n");
        return -1;
    }
    //printf("mqtt subscribe success\r\n");
    return 0;    
}

int32_t mqtt_init(struct GtcParams *params){
    int32_t ret = 0;
    memset(&mqtt_base, 0, sizeof(mqtt_base));
    mqtt_base.address = params->server_addr;
    mqtt_base.port = params->server_port;
    mqtt_base.username = params->username;
    mqtt_base.password = params->password;
    mqtt_base.topic = params->dev_id;
    
    NetworkInit(&mqtt_base.network);
    MQTTClientInit(&mqtt_base.client, &mqtt_base.network, MQTT_CMD_TIMEOUT, 
                    mqtt_base.sendbuf, sizeof(mqtt_base.sendbuf), mqtt_base.recvbuf, sizeof(mqtt_base.recvbuf));
    
    mqtt_base.queue = os_queue_create(MQTT_SENT_QUEUE_NUM, sizeof(struct MqttSendMsg));
    if (mqtt_base.queue == 0){
        return -1;
    }

    return ret;
}

void gtc_mqtt_send_resp(enum GtcMqttCmdType cmd_type, void * cmd, uint8_t Qos){

}

